package com.zhaoyd.redislock.controller;

import com.zhaoyd.redislock.core.SimpleRedisClient;
import com.zhaoyd.redislock.core.lock.SyncLock;
import com.zhaoyd.redislock.core.lock.SyncLockFactory;
import com.zhaoyd.redislock.core.lock.SyncLockable;
import com.zhaoyd.redislock.util.AssertUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

/**
 * @author zhaoyd
 * @date 2020-09-23
 */
@RestController
public class DemoController {
    @Resource
    private SimpleRedisClient simpleRedisClient;

    /**
     *  demo1
     *  代码显式获取/释放锁
     */
    @RequestMapping("demo1")
    public String demo1() throws InterruptedException{
        String lockKey = "demo1LockKey";
        String lockValue = "demo1LockValue";
        long expireSecond = 10;
        //循环获取锁
        while (true){
            boolean isLock = simpleRedisClient.setNX(lockKey, lockValue, expireSecond);
            if(isLock){
                //获取到锁，跳出循环
                break;
            }else{
                //休眠50ms
                Thread.sleep(50L);
            }
        }
        //获取到锁，执行业务逻辑
        try {
            //模拟业务逻辑，执行5s
            Thread.sleep(5000L);
        }catch (Exception e){
            // demo代码忽略异常处理
        }finally {
            //释放锁
            simpleRedisClient.del(lockKey);
        }
        return "demo1";
    }

    @Resource
    private SyncLockFactory syncLockFactory;
    /**
     *  demo2
     *  封装获取/释放锁 SyncLock
     */
    @RequestMapping("demo2")
    public String demo2() throws InterruptedException{
        String lockKey = "demo2LockKey";
        String lockValue = "demo2LockValue";
        long expireSecond = 10;
        //创建锁对象
        SyncLock syncLock = new SyncLock(lockKey, simpleRedisClient, expireSecond*1000L, null);
        //阻塞获取锁
        Boolean isLock = syncLock.lock();
        AssertUtils.isTrue(isLock, "获取锁失败,超时");
        //获取到锁，执行业务逻辑
        try {
            //模拟业务逻辑，执行5s
            Thread.sleep(5000L);
        }catch (Exception e){
            // demo代码忽略异常处理
        }finally {
            //释放锁
            syncLock.unLock();
        }
        return "demo2";
    }

    /**
     *  demo3
     *  aop注解实现
     */
    @SyncLockable()
    @RequestMapping("demo3")
    public String demo3() throws InterruptedException{
        //模拟业务逻辑，执行5s
        Thread.sleep(5000L);
        return "demo3";
    }
    /**
     *  demo4
     *  aop注解实现 + el表达式
     */
    @SyncLockable(key = "demo4#{#whId+'_'+#sku}",expire = 1000000)
    @RequestMapping("demo4")
    public String demo4(Integer whId,String sku) throws InterruptedException{
        //模拟业务逻辑，执行5s
        Thread.sleep(5000L);
        return "demo4";
    }

}
